
import datetime
import json

import re
import time
import uuid

from celery import group
from injector import inject
from dataclasses import  dataclass
from functools import wraps

from sqlalchemy import desc, func, cast, Date, DateTime
from internal.entitry.account_entitry import ACCESS_TOKEN, CACHE_PROXY
from internal.entitry.tickets_entitry import TICKETS_URL, TicketsStstaus, USER_SUB_URL, PRODUCT_PC_URL, \
    DETAILS_URL, CANCEL_URL, ProxyType
from internal.lib.kdl.proxy_utils import get_proxy
from internal.lib.sign import get_headers
from internal.lib.utils import  serialize_model, expired_datetime
from internal.schema import CreateTicketsForm
from internal.schema.tickets_schema import TicketsWithListPageSchema, AgencyCheckGuideSchema, TourGuideWithListSchema
from internal.service.base_service import BaseService
from pkg.paginator import Paginator
from pkg.sqlalchemy import  SQLAlchemy
from internal.exception.exception import FailException, UnauthorizedException,NotFoundException
from internal.model import TravelAgency, TourGuide, Member, MemberItem
from redis import  Redis
from internal.task.tickets_task import rservation
import  requests
from internal.exception.exception import ValidateErrorException
from internal.service.acccount_service import  AccountService
def retry_until_success_or_deadline(deadline_time_str="17:00", delay=0.001, max_retries=None):
    """
    改进版重试装饰器，支持多种异常处理和更智能的重试逻辑
    :param deadline_time_str: 截止时间字符串，格式 "HH:MM"
    :param delay: 基础重试间隔时间（秒）
    :param max_retries: 最大重试次数（可选）
    """

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(f"🎯 🎯 🎯 进入重试装饰器: {func.__name__} 🎯 🎯 🎯")
            print(f"   参数: args长度={len(args)}, kwargs={list(kwargs.keys())}")

            deadline_hour, deadline_minute = map(int, deadline_time_str.split(':'))
            attempt_count = 0
            start_time = datetime.datetime.now()

            # 可重试的异常类型
            retryable_exceptions = (FailException, requests.RequestException, ConnectionError)

            while True:
                print(f"🔄 重试循环开始, 尝试次数: {attempt_count}")

                # 🔥 停止检查：检查批次停止和旅行社停止
                if len(args) > 0 and hasattr(args[0], 'is_stopped'):
                    try:
                        print(f"🔍 开始停止检查...")

                        # 提取参数（只需要 bash_id 和 agency_id）
                        bash_id = kwargs.get('bash_id') or (args[1] if len(args) > 1 else None)
                        lvs = kwargs.get('lvs') or (args[3] if len(args) > 3 else None)

                        print(f"🔍 参数提取结果: bash_id={bash_id}, lvs类型={type(lvs)}")

                        # 提取旅行社ID
                        agency_id = None
                        if lvs:
                            # 方法1: 直接从对象属性获取
                            if hasattr(lvs, 'id') and lvs.id:
                                agency_id = lvs.id
                                print(f"🔍 从对象属性获取agency_id: {agency_id}")

                            # 方法2: 如果agency_id为None，从数据库查询
                            elif hasattr(lvs, 'id') and lvs.id:
                                try:
                                    print(f"🔍 agency_id为None，尝试从数据库查询...")
                                    from app.http.module import injector
                                    from pkg.sqlalchemy import SQLAlchemy
                                    from internal.model.travel_agency import TravelAgency

                                    db = injector.get(SQLAlchemy)
                                    agency = db.session.query(TravelAgency).filter(TravelAgency.id == lvs.id).first()
                                    if agency and agency.id:
                                        agency_id = agency.id
                                        print(f"🔍 从数据库查询到agency_id: {agency_id}")
                                    else:
                                        print(f"❌ 数据库中没有找到agency_id")
                                except Exception as db_error:
                                    print(f"⚠️ 数据库查询失败: {str(db_error)}")

                        print(f"🔍 最终检查参数: bash_id={bash_id}, agency_id={agency_id}")

                        # 检查停止状态（只需要 bash_id 和 agency_id）
                        if bash_id and agency_id:  # 确保两个参数都不为空
                            is_stopped, stop_type = args[0].is_stopped( bash_id, agency_id)
                            print(f"🛑 停止检查最终结果: is_stopped={is_stopped}, stop_type={stop_type}")

                            if is_stopped:
                                print(f"🚫 🚫 🚫 检测到{stop_type}级别停止，终止重试 🚫 🚫 🚫")
                                print(f"   停止详情: bash_id={bash_id}, agency_id={agency_id}")
                                raise FailException(f"用户手动停止({stop_type}级别)")
                            else:
                                print(f"🟢 未检测到停止，继续执行")
                        else:
                            print(f"⚠️ 参数不全，跳过停止检查: bash_id={bash_id}, agency_id={agency_id}")

                    except FailException as e:
                        # 如果是停止异常，直接抛出
                        if "用户手动停止" in str(e):
                            raise e
                        else:
                            print(f"⚠️ 停止检查中的业务异常: {str(e)}")
                    except Exception as e:
                        # 停止检查本身的技术异常，记录但继续流程
                        print(f"⚠️ 停止检查技术异常: {str(e)}")
                else:
                    print(
                        f"⚠️ 无法进行停止检查: args长度={len(args)}, 有is_stopped方法={hasattr(args[0], 'is_stopped') if len(args) > 0 else '无args'}")

                # ✅ 保持原有的时间检查逻辑
                current_time = datetime.datetime.now()
                today_deadline = current_time.replace(
                    hour=deadline_hour, minute=deadline_minute, second=0, microsecond=0
                )

                # 检查截止时间
                if current_time >= today_deadline:
                    elapsed = (current_time - start_time).total_seconds()
                    attempts_per_second = attempt_count / elapsed if elapsed > 0 else attempt_count

                    print(f"⏰ 已超过截止时间 {deadline_time_str}，终止重试")

                    try:
                        if len(args) > 0 and hasattr(args[0], 'update_member_status_on_timeout'):

                            # 调用服务层的方法更新状态
                            member = kwargs.get('member') or (args[4] if len(args) > 4 else None)
                            if member:
                                args[0].update_member_status_on_timeout(member.id)
                    except Exception as update_error:
                        print(f"⚠️ 超时状态更新失败: {str(update_error)}")

                    raise FailException(
                        f"已超过截止时间 {deadline_time_str}，总尝试次数: {attempt_count}，频率: {attempts_per_second:.1f}次/秒"
                    )

                # 检查最大重试次数
                if max_retries and attempt_count >= max_retries:
                    elapsed = (current_time - start_time).total_seconds()
                    attempts_per_second = attempt_count / elapsed if elapsed > 0 else attempt_count
                    print(f"🔚 达到最大重试次数 {max_retries}，终止重试")
                    raise FailException(
                        f"达到最大重试次数 {max_retries}，总耗时: {elapsed:.1f}秒，频率: {attempts_per_second:.1f}次/秒"
                    )

                try:
                    # ✅ 保持原有的函数执行逻辑
                    print(f"🟢 执行函数: {func.__name__}, 尝试次数: {attempt_count}")
                    result = func(*args, **kwargs)
                    end_time = datetime.datetime.now()
                    total_duration = (end_time - start_time).total_seconds()
                    print(f"🎉 成功！耗时: {total_duration:.3f}秒，尝试次数: {attempt_count}")
                    return result

                except retryable_exceptions as e:
                    print(f"❌ 遇到可重试异常: {str(e)}")

                    # 🔥 在异常处理中也检查停止
                    stop_exception = None
                    if len(args) > 0 and hasattr(args[0], 'is_stopped'):
                        try:
                            print(f"🔍 异常处理中检查停止状态...")
                            bash_id = kwargs.get('bash_id') or (args[1] if len(args) > 1 else None)
                            lvs = kwargs.get('lvs') or (args[3] if len(args) > 3 else None)

                            print(f"🔍 异常处理中参数提取结果: bash_id={bash_id}, lvs类型={type(lvs)}")

                            # 提取旅行社ID - 完整逻辑
                            agency_id = None
                            if lvs:
                                # 方法1: 直接从对象属性获取
                                if hasattr(lvs, 'id') and lvs.id:
                                    agency_id = lvs.id
                                    print(f"🔍 异常处理中从对象属性获取agency_id: {agency_id}")

                                # 方法2: 如果agency_id为None，从数据库查询
                                elif hasattr(lvs, 'id') and lvs.id:
                                    try:
                                        print(f"🔍 异常处理中agency_id为None，尝试从数据库查询...")
                                        from app.http.module import injector
                                        from pkg.sqlalchemy import SQLAlchemy
                                        from internal.model.travel_agency import TravelAgency

                                        db = injector.get(SQLAlchemy)
                                        agency = db.session.query(TravelAgency).filter(
                                            TravelAgency.id == lvs.id).first()
                                        if agency and agency.id:
                                            agency_id = agency.id
                                            print(f"🔍 异常处理中从数据库查询到agency_id: {agency_id}")
                                        else:
                                            print(f"❌ 异常处理中数据库中没有找到agency_id")
                                    except Exception as db_error:
                                        print(f"⚠️ 异常处理中数据库查询失败: {str(db_error)}")

                            print(f"🔍 异常处理中最终检查参数: bash_id={bash_id}, agency_id={agency_id}")

                            # 检查停止状态
                            if bash_id and agency_id:  # 确保两个参数都不为空
                                is_stopped, stop_type = args[0].is_stopped(bash_id, agency_id)
                                print(f"🛑 异常处理中停止检查结果: is_stopped={is_stopped}, stop_type={stop_type}")

                                if is_stopped:
                                    print(f"🛑 异常处理中检测到{stop_type}级别停止，立即终止重试")
                                    # 🔥 创建停止异常但不立即抛出，保存到变量
                                    stop_exception = FailException(f"用户手动停止({stop_type}级别)")
                            else:
                                print(f"⚠️ 异常处理中参数不全，跳过停止检查: bash_id={bash_id}, agency_id={agency_id}")

                        except Exception as check_error:
                            print(f"⚠️ 异常处理中停止检查异常: {str(check_error)}")
                            import traceback
                            traceback.print_exc()

                    # 🔥 如果检测到停止，立即抛出异常终止循环
                    if stop_exception:
                        print(f"🚫 抛出停止异常，终止重试循环")
                        raise stop_exception

                    # 🔥 只有在没有检测到停止的情况下才继续重试逻辑
                    attempt_count += 1
                    current_time = datetime.datetime.now()

                    # 检查是否超过截止时间
                    if current_time >= today_deadline:
                        elapsed = (current_time - start_time).total_seconds()
                        attempts_per_second = attempt_count / elapsed if elapsed > 0 else attempt_count
                        print(f"⏰ 异常处理中检测到超过截止时间 {deadline_time_str}")

                        try:
                            if len(args) > 0 and hasattr(args[0], 'update_member_status_on_timeout'):

                                # 调用服务层的方法更新状态
                                member = kwargs.get('member') or (args[4] if len(args) > 4 else None)
                                if member:
                                    args[0].update_member_status_on_timeout(member.id)
                        except Exception as update_error:
                            print(f"⚠️ 超时状态更新失败: {str(update_error)}")

                        raise FailException(
                            f"已超过截止时间 {deadline_time_str}，总尝试次数: {attempt_count}，频率: {attempts_per_second:.1f}次/秒"
                        ) from e

                    # 检查最大重试次数
                    if max_retries and attempt_count >= max_retries:
                        elapsed = (current_time - start_time).total_seconds()
                        attempts_per_second = attempt_count / elapsed if elapsed > 0 else attempt_count
                        print(f"🔚 异常处理中达到最大重试次数 {max_retries}")
                        raise FailException(
                            f"达到最大重试次数 {max_retries}，总耗时: {elapsed:.1f}秒，频率: {attempts_per_second:.1f}次/秒"
                        )

                    # 智能延迟：随着重试次数增加而增加延迟时间
                    current_delay = delay * (1 + attempt_count * 0.1)  # 每次增加10%

                    # 每100次尝试打印一次日志
                    if attempt_count % 100 == 0:
                        elapsed = (current_time - start_time).total_seconds()
                        attempts_per_second = attempt_count / elapsed if elapsed > 0 else attempt_count
                        remaining_time = (today_deadline - current_time).total_seconds()
                        print(f"⏳ 尝试中... 次数: {attempt_count}, 频率: {attempts_per_second:.1f}次/秒")
                        print(f"   剩余时间: {remaining_time:.0f}秒, bash_id={bash_id}")

                    # 添加随机抖动避免同步重试
                    import random
                    jitter = random.uniform(0.9, 1.1)
                    final_delay = current_delay * jitter

                    print(f"   💤 延迟 {final_delay:.3f}秒后重试 (attempt {attempt_count})")
                    time.sleep(final_delay)
            print(f"🏁 重试装饰器结束")

        return wrapper

    return decorator
@inject
@dataclass
class TicketsService(BaseService):
    redis_client: Redis
    db: SQLAlchemy
    account_service:AccountService
    #旅行社入库/成员落库
    def lvs(self,req:AgencyCheckGuideSchema):
        uid = str(uuid.uuid4())
        for bean in req.data.data:
            user = bean.get("user")
            for date in user.get("playDate"):

                guide_count = (self.db.session.query(Member)
                               .join(TravelAgency, Member.travel_agency_id == TravelAgency.id)
                               .filter(TravelAgency.bash_id == bean.get("bash_id"),
                                       TravelAgency.playDate == date,
                                       Member.status.in_([TicketsStstaus.RESERVATION_SUCCESS.value,TicketsStstaus.ERROR.value]))
                               .count())
                if guide_count>0:
                    raise FailException("同一个导游不可预约重复日期")

                # 旅行社入库
                travel_agency = TravelAgency(
                    bash_id=bean.get("bash_id"),
                    grounp_id = uid,
                    playDate=date,
                    travel_agency_name=bean.get("travelAgencyName")
                )
                self.db.session.add(travel_agency)
                self.db.session.flush()
                # 成员落库
                member = Member(
                    bash_id=bean.get("bash_id"),
                    playDate=date,
                    grounp_id=uid,

                    travel_agency_id=travel_agency.id,
                    status=TicketsStstaus.PADDING.value
                )
                self.db.session.add(member)
                self.db.session.flush()

                for item in user.get("addTourists"):
                    member_item_res = self.db.session.query(MemberItem).filter(MemberItem.card_number ==item.get("cardNumber"),MemberItem.bash_id==bean.get("bash_id"),MemberItem.grounp_id==member.grounp_id).one_or_none()
                    if member_item_res is not None:
                        continue

                    member_item = MemberItem(
                        bash_id=bean.get("bash_id"),
                        grounp_id = uid,
                        touristName=item.get("touristName"),
                        card_type=item.get("cardType"),
                        card_number=item.get("cardNumber"),
                        touristMobile=item.get("touristMobile"),
                        origin=item.get("origin")
                    )
                    self.db.session.add(member_item)
        self.db.session.commit()

    def update_member_status_on_timeout(self, member_id: str):
        """超时时更新成员状态"""
        try:
            with self.db.auto_commit():
                member = self.db.session.query(Member).filter(Member.id == member_id).first()
                if member and member.status == TicketsStstaus.ERROR.value:
                    member.status = TicketsStstaus.LAST_ERROR.value
                    print(f"⏰ 超时回调: 已更新成员 {member_id} 状态为 LAST_ERROR")
        except Exception as e:
            print(f"⚠️ 超时状态更新异常: {str(e)}")
    #导游落库
    def create_tickets_new(self, req:CreateTicketsForm):
        objs=[]
        #导游信息
        for tickets_bean in req.data.data:
            uid = str(uuid.uuid4())
            item  = tickets_bean.get("agencyCheckGuides")
            tour_guide_res = self.db.session.query(TourGuide).filter(TourGuide.card_number == item.get("guideIdentify")).one_or_none()
            if tour_guide_res is not None:
                continue
            tour_guide = TourGuide(
                bash_id=uid,
                tour_guide_name=item.get("guideName"),
                card_type=item.get("cardType"),
                status=TicketsStstaus.PADDING.value,
                card_number=item.get("guideIdentify"),
                travel_agency_card_num=item.get("guideNo"),
                travel_agency_phone=item.get("guideMobile")
            )
            objs.append(
                {
                    "bash_id": uid,
                    "guideName": item.get("guideName")
                }
            )
            self.db.session.add(tour_guide)
        self.db.session.commit()
        return objs

    def stop_agency_reservation(self, agency_id: str):

        """
        停止特定旅行社的所有预约
        """
        with self.db.auto_commit():
            # 查找旅行社
            agency = self.db.session.query(TravelAgency).filter(TravelAgency.id == agency_id).one_or_none()
            member = self.db.session.query(Member).filter(Member.travel_agency_id == agency_id).one_or_none()

            if member.status in [TicketsStstaus.RESERVATION_SUCCESS.value,TicketsStstaus.LAST_ERROR.value]:
                raise  FailException("停止失败，该团队预约已有结果")
            if member.status in [TicketsStstaus.TIME_OUT.value]:
                raise  FailException("该订单已过期")
            if not agency:
                raise NotFoundException(f"旅行社 {agency_id} 不存在")

            # 停止该旅行社下的所有成员预约
            member.status = TicketsStstaus.STOP.value
            print(f"✅ 已停止旅行社 {agency.travel_agency_name} 的所有预约")

        # 设置Redis停止标志
        self._set_stop_flag("agency", agency_id, agency.bash_id)

    def stop_guide_reservation(self, bash_id: str):
        """
        通过批次ID停止导游的所有预约
        """
        with self.db.auto_commit():
            # 查找该批次下的所有导游
            guides = self.db.session.query(TourGuide).filter(TourGuide.bash_id == bash_id).one_or_none()
            if not guides:
                raise NotFoundException(f"批次 {bash_id} 下没有找到导游")
            if guides.status in  [TicketsStstaus.RESERVATION_SUCCESS.value,TicketsStstaus.LAST_ERROR.value]:
                raise  FailException("停止失败，该导游预约已有结果")
            stopped_guides = []
            total_members = 0

            for guide in guides:
                # 停止导游状态
                guide.enabled = 0
                # 停止该导游下的所有成员预约
                member = self.db.session.query(Member).filter(Member.bash_id == guide.bash_id).one_or_none()
                member.status = TicketsStstaus.STOP.value

                stopped_guides.append(guide.tour_guide_name)


            print(f"🎯 已停止批次 {bash_id} 的所有导游预约")
            print(f"   共停止 {len(guides)} 个导游，{total_members} 个成员")

        # 设置批次级别的停止标志（停止整个批次）
        self._set_stop_flag("batch", bash_id, bash_id)


    def _set_stop_flag(self, stop_type: str, identifier: str, bash_id: str):
        """
        设置Redis停止标志
        """
        try:
            import redis

            stop_key = f"reservation_stop:{stop_type}:{identifier}"
            stop_info = {
                "stop_type": stop_type,
                "identifier": identifier,
                "bash_id": bash_id,
                "timestamp": datetime.datetime.now().isoformat()
            }

            # 使用同步Redis客户端
            self.redis_client.setex(stop_key, 24 * 3600, json.dumps(stop_info))

            print(f"   🛑 已设置停止标志: {stop_key}")

        except Exception as e:
            print(f"   ⚠️ 设置停止标志失败: {str(e)}")

    def is_stopped(self, bash_id: str, agency_id: str = None):
        """
        检查是否被停止，同时验证实体是否存在
        """
        try:
            # 1. 检查批次级别停止
            batch_stop_key = f"reservation_stop:batch:{bash_id}"
            if self.redis_client.exists(batch_stop_key):
                return True, "batch"

            # 2. 检查旅行社级别停止（添加存在性验证）
            if agency_id:
                # 🔥验证旅行社是否还存在
                agency_exists = self.db.session.query(TravelAgency).filter(
                    TravelAgency.id == agency_id
                ).first()

                if not agency_exists:
                    print(f"🛑 旅行社 {agency_id} 不存在，视为已停止")
                    return True, "agency"  # 已删除的实体视为停止

                agency_stop_key = f"reservation_stop:agency:{agency_id}"
                if self.redis_client.exists(agency_stop_key):
                    return True, "agency"

            return False, None

        except Exception as e:
            print(f"⚠️ 停止检查失败: {str(e)}")
            return False, None


    #导游预约
    @retry_until_success_or_deadline(deadline_time_str="21:59", delay=5)
    def rservation_tickets(self,bash_id:str,tickets_bean:TourGuide,lvs:TravelAgency, member:Member,type:str,secret_id:str=None,secret_key:str=None):
        req_session = requests.session()
        # client = Client(secret_id="ok5zvve3z2jqf5rj5338", secret_key="pef5ywkyl2sy5rjfn1n4u3yj6zibn0tp")
        # ips = client.get_dps(2000, sign_type='token', format='text', area='北京,上海,云南,广东', pt=2)
        # proxy_list = ips.strip().split('\n')
        cache = ACCESS_TOKEN.format(user_id=tickets_bean.user_id)
        token = self.redis_client.get(cache)
        headers = get_headers(TICKETS_URL,token)
        proxy = {}
        if type == ProxyType.PROXY.value:
            status = self.account_service.getorder_info(secret_id,secret_key)
            print("================================")
            print(status)
            print("================================")
            if status =="VALID":
                key = CACHE_PROXY.format(secret_id=secret_id)
                proxy_account = json.loads(self.redis_client.get(key))
                username = proxy_account.get("username")
                password = proxy_account.get("password")
                proxy = get_proxy(username, password)
            else:
                with self.db.auto_commit():
                    member.status = TicketsStstaus.LAST_ERROR.value
                return "由于代理账户已停用，已停止"

        if self.is_batch_completed(bash_id):
            print(f"🎯 rservation_tickets 检测到批次 {bash_id} 已完成，直接返回")
            return True

        merge_headers = {
            **headers,
            "Authorization": f"Bearer {token}"
        }
        agency_check_guides = [
            {
                "guideName":tickets_bean.tour_guide_name,
                "cardType":tickets_bean.card_type,
                "guideIdentify":tickets_bean.card_number,
                "guideNo":tickets_bean.travel_agency_card_num,
                "guideMobile":tickets_bean.travel_agency_phone,
                "masterStatus": 1
            }
        ]
        ojs = {
            "travelAgencyName":lvs.travel_agency_name,
            "channelId":"01",
            "agencyCheckGuides":agency_check_guides
        }
        print("哈哈哈哈哈哈哈哈哈")
        print(ojs)
        print("哈哈哈哈哈哈哈哈哈")
        # for attempt in range(3):
        #     proxy = random.choice(proxy_list)
        #     proxies = {
        #         'http': f'http://{proxy}',
        #         'https': f'https://{proxy}'
        #     }
        try:
            print("========================================proxy====================================================")
            print(proxy)
            print("========================================proxy====================================================")
            req = req_session.request(
                method="post",
                url=TICKETS_URL,
                json=ojs,
                proxies=proxy,
                verify=False,
                headers=merge_headers
            )
            data = req.json()
            print(data)
            print("============================导游预约===============================")
            if data.get("code") == 401:
                raise UnauthorizedException("token，请登录后尝试")
            if data.get("code") == 200:
                self.update(
                    tickets_bean,
                    status=TicketsStstaus.RESERVATION_SUCCESS.value,
                )
                print(3)
                flag = self.rservation_user(data.get("data").get("guideMarks"), bash_id, tickets_bean.travel_agency_phone,
                                            member.id, lvs.id, tickets_bean.id,proxy)
                if flag:
                    with self.db.auto_commit():
                        member.status = TicketsStstaus.RESERVATION_SUCCESS.value
                    return True
            else:
                print("=================================rservation_tickets===============================")
                print(data.get("msg"))
                print("=================================rservation_tickets===============================")
                raise FailException(data.get("msg"))
        except Exception as e:
            raise  FailException(str(e))
    #获取列表
    def user_with_tickets_list(self):
        pass

    def is_batch_completed(self, bash_id: str):
        """检查批次是否已完成"""
        batch_completed_key = f"batch_completed:{bash_id}"
        return self.redis_client.exists(batch_completed_key)
    #取消预约旅行社
    def cancel_agency(self,order_no:str,bash_id:str,agency_id:str):


        member = self.db.session.query(Member).filter(Member.travel_agency_id == agency_id).one_or_none()
        if member.status in [TicketsStstaus.TIME_OUT.value]:
            raise FailException("该订单已过期")

        guide = self.db.session.query(TourGuide).filter(TourGuide.bash_id == bash_id).one_or_none()
        print(guide.user_id)
        cache = ACCESS_TOKEN.format(user_id=guide.user_id)
        token = self.redis_client.get(cache)
        url = f"{CANCEL_URL}/{order_no}?_={int(time.time()*1000)}"
        headers = get_headers(url, token)
        merge_headers = {
            **headers,
            "Authorization": f"Bearer {token}"
        }
        print(token)
        req_session = requests.session()

        print(url)
        print("========================================")
        req = req_session.delete(url, verify=False, headers=merge_headers)
        try:
            data = req.json()
            print(data)
            if data.get("code") not in [10016,"10016"]:
                raise FailException(data.get("msg"))
            with self.db.auto_commit():
                guide.status = TicketsStstaus.PADDING.value

                self.db.session.query(Member).filter(Member.travel_agency_id == agency_id).update({
                    "status": TicketsStstaus.CANCELED.value,
                })
        except Exception as e:
            raise FailException(str(e))




    #获取导游列表
    def get_tour_guide_with_list(self, req: TourGuideWithListSchema):

        # 构建查询条件
        paginator =  Paginator(db=self.db,req=req)
        filters = []
        if req.travel_agency_phone.data:
            filters.append(TourGuide.travel_agency_phone == req.travel_agency_phone.data)
        if req.name.data:
            filters.append(TourGuide.tour_guide_name.ilike(f"%{req.name.data}%"))
        if req.bash_id.data and str(req.bash_id.data)!="":
            bash_ids = req.bash_id.data
            if not re.search(r'[，,]', bash_ids):
                # 不包含逗号，提示错误
                raise ValidateErrorException("多个批次id请使用逗号分割")
            bash_ids = re.split(r'[，,]', req.bash_id.data)
            bash_ids = [id.strip() for id in bash_ids if id.strip()]
            filters.append(TourGuide.bash_id.in_(bash_ids))
        if req.enabled.data:
            filters.append(TourGuide.enabled == int(req.enabled.data))

        # 查询导游数据
        tour_guides = paginator.paginate(self.db.session.query(TourGuide).filter(*filters))

        data_tree = []

        for tour_guide in tour_guides:
            # 获取token信息
            cache = ACCESS_TOKEN.format(user_id=tour_guide.user_id)
            token = self.redis_client.get(cache)
            ttl = self.redis_client.ttl(cache)

            # 查询关联的旅行社
            travel_agencies = self.db.session.query(TravelAgency).join(
                Member, TravelAgency.id == Member.travel_agency_id
            ).filter(
                TravelAgency.bash_id == tour_guide.bash_id,
                Member.status != TicketsStstaus.RESERVATION_SUCCESS.value,
                TravelAgency.deleted == False
            ).all()

            # 查询所有相关成员（一次性查询提高效率）
            all_member_items = self.db.session.query(MemberItem).filter(
                MemberItem.bash_id == tour_guide.bash_id,
            ).all()

            # 构建成员字典，按bash_id分组（如果需要的话）
            members_by_bash_id = {}
            for item in all_member_items:
                if item.grounp_id not in members_by_bash_id:
                    members_by_bash_id[item.grounp_id] = []
                members_by_bash_id[item.grounp_id].append(item)

            # 构建导游节点
            guide_node = {
                'id': tour_guide.id,
                'bash_id': tour_guide.bash_id,
                'travel_agency_card_num': tour_guide.travel_agency_card_num,
                "card_number":tour_guide.card_number,
                "travel_agency_phone": tour_guide.travel_agency_phone,
                "name": tour_guide.tour_guide_name,
                "enabled":tour_guide.enabled,
                "created_at": tour_guide.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                "updated_at": tour_guide.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                "token": token,
                "expired_datetime":   expired_datetime(ttl) if token else None,
                'travel_agencies': []  # 只有旅行社子节点
            }

            # 构建旅行社子节点，并将成员分配到对应的旅行社
            for agency in travel_agencies:
                if not agency.order_no:  # 过滤条件
                    agency_node = {
                        'id': agency.id,
                        'bash_id': agency.bash_id,
                        'grounp_id':agency.grounp_id,
                        'travel_agency_name': agency.travel_agency_name,
                        'playDate':agency.playDate,
                        'member_items': []  # 该旅行社下的成员
                    }
                    # 将属于该旅行社的成员添加进来
                    if agency.grounp_id in members_by_bash_id:
                        for item in members_by_bash_id[agency.grounp_id]:
                            member_node = {
                                'id': item.id,
                                'bash_id': item.bash_id,
                                'touristName': item.touristName,
                                "card_number": item.card_number,
                                "touristMobile": item.touristMobile,
                                "origin": item.origin
                            }
                            agency_node['member_items'].append(member_node)

                    guide_node['travel_agencies'].append(agency_node)

            data_tree.append(guide_node)

        return data_tree,paginator


    def _is_seven_days_later(self,date_str, date_format="%Y-%m-%d"):
        from datetime import datetime
        """
        判断日期字符串是否与当前时间相隔7天
        """
        target_date = datetime.strptime(date_str, date_format)
        today = datetime.now()

        # 计算日期差（忽略时间部分）
        date_difference = (target_date.date() - today.date()).days
        return date_difference == 7

    def is_noon_exact(self):
        from datetime import datetime
        """判断当前时间是否是12点整（精确到秒）"""
        now = datetime.now()
        return now.hour == 12 and now.minute == 0 and now.second == 0
    def update_paly_date(self,date_str:str,agency_id:str):
        with self.db.auto_commit():
            self.db.session.query(TravelAgency).filter(TravelAgency.id == agency_id).update({
                'playDate': date_str,
            })
            self.db.session.query(Member).filter(Member.travel_agency_id == agency_id).update({
                'playDate': date_str,
            })


    #启用/禁用
    def update_enabled(self, enabled: int, guide_id: list):
        with self.db.auto_commit():
            # 检查存在性
            existing_count = self.db.session.query(TourGuide).filter(
                TourGuide.id.in_(guide_id)
            ).count()

            if existing_count != len(guide_id):
                raise NotFoundException("部分导游不存在")

            # 批量更新
            updated_count = self.db.session.query(TourGuide).filter(
                TourGuide.id.in_(guide_id)
            ).update(
                {"enabled": enabled},
                synchronize_session=False
            )
        return updated_count

    #重新发起预约(批量执行Celery异步)
    def re_sub(self,agency_id):
        from datetime import datetime
        current_time = datetime.now()
        if current_time.hour >= 22:
            raise FailException("已超过预约截止时间22:00")
        with self.db.auto_commit():
            member = self.db.session.query(Member).filter(Member.travel_agency_id == agency_id).one_or_none()
            guide = member.get_guide #获取导游
            agency = member.get_agency  # 获取旅行社
            if guide is None:
                raise  FailException("该导游不存在")
            if member is None and agency is None:
                raise FailException("该旅行社不存在")
            if member.status not in [TicketsStstaus.STOP.value,TicketsStstaus.LAST_ERROR.value,TicketsStstaus.CANCELED.value]:
                raise FailException("该订单不可预约")
            if member.status in [TicketsStstaus.TIME_OUT.value]:
                raise FailException("该订单已过期")
            if guide.enabled == -1:
                raise FailException(f"该导游：{guide.tour_guide_name}已被禁用，请启用后预约")

            if not guide.user_id:
                raise UnauthorizedException(f"导游 '{guide.tour_guide_name}' 未登录,请登陆后重试")
            guide_count = (self.db.session.query(Member)
                           .join(TravelAgency, Member.travel_agency_id == TravelAgency.id)
                           .filter(TravelAgency.bash_id == member.bash_id,
                                   TravelAgency.playDate == member.playDate,
                                   Member.status.in_(
                                       [TicketsStstaus.RESERVATION_SUCCESS.value, TicketsStstaus.ERROR.value]))
                           .count())
            if guide_count > 0:
                raise FailException("同一个导游不可预约重复日期")

            member.status = TicketsStstaus.ERROR.value
        # 清除批次完成标识
        batch_completed_key = f"batch_completed:{guide.bash_id}"
        if self.redis_client.exists(batch_completed_key):
                self.redis_client.delete(batch_completed_key)
                print(f"🧹 清除批次完成标志: {batch_completed_key}")
        # 清除停止标识
        agency_stop_key = f"reservation_stop:agency:{agency.id}"
        if self.redis_client.exists(agency_stop_key):
            self.redis_client.delete(agency_stop_key)

        tour_guide_dict = {
                "id": guide.id,
                "bash_id": guide.bash_id,
                "user_id": guide.user_id,
                "tour_guide_name": guide.tour_guide_name,
                "card_type": guide.card_type,
                "card_number": guide.card_number,
                "travel_agency_card_num": guide.travel_agency_card_num,
                "travel_agency_phone": guide.travel_agency_phone,
                "status": guide.status,
                "updated_at": guide.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                "created_at": guide.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
        travel_agency_dict = {
                "id": agency.id,
                "bash_id": agency.bash_id,
                "grounp_id": agency.id,
                "travel_agency_name": agency.travel_agency_name,
                "get_number": agency.get_number,
                "order_no": agency.order_no,
                "start_time": agency.start_time,
                "end_time": agency.end_time,
                "updated_at": agency.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                "created_at": agency.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
        member_dict = {
                "id": member.id,
                "bash_id": member.bash_id,
                "travel_agency_id": member.travel_agency_id,
                "status": member.status,
                "playDate": member.playDate,
                "created_at": member.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                "updated_at": member.updated_at.strftime('%Y-%m-%d %H:%M:%S')
        }
        rservation.delay(
                bash_id=guide.bash_id,
                agency_id=agency.id,
                grounp_id=member.grounp_id,
                lv=json.dumps(travel_agency_dict),
                tickets_bean=json.dumps(tour_guide_dict),
                member=json.dumps(member_dict)
            )


    #发起预约(批量执行Celery异步)
    def sub(self, ids: list,grounp_ids:list,type=ProxyType.CUSTOM.value,secret_id:str=None,secret_key=None):
        if type == ProxyType.PROXY.value:
           status =  self.account_service.getorder_info(secret_id,secret_key)
           print("================================")
           print(status)
           print("================================")
           if status != "VALID":
               raise  FailException("代理订单失效或已停止")
        from datetime import datetime
        current_time = datetime.now()
        if current_time.hour >= 22:
            raise FailException("已超过预约截止时间22:00")
        tasks = []
        travel_guide = self.db.session.query(TourGuide).filter(TourGuide.id.in_(ids)).all()
        if len(travel_guide) == 0:
            raise NotFoundException("导游信息不存在，请检查后提交")

        meember_grounp_count = self.db.session.query(Member).filter(
            Member.status == TicketsStstaus.RESERVATION_SUCCESS.value,

            Member.grounp_id.in_(grounp_ids)
        ).count()
        if meember_grounp_count > 0:
            raise FailException("该成员组已有预约成功的数据，不可重复录入，请刷新重试")

        for guide in travel_guide:
            if guide.enabled == -1:
                raise  FailException(f"该导游：{guide.tour_guide_name}已被禁用，请启用后预约")

            if not guide.user_id:
                raise UnauthorizedException(f"导游 '{guide.tour_guide_name}' 未登录,请登陆后重试")

            batch_stop_key = f"reservation_stop:batch:{guide.bash_id}"
            if self.redis_client.exists(batch_stop_key):
                self.redis_client.delete(batch_stop_key)

            batch_completed_key = f"batch_completed:{guide.bash_id}"
            if self.redis_client.exists(batch_completed_key):
                self.redis_client.delete(batch_completed_key)
                print(f"🧹 清除批次完成标志: {batch_completed_key}")
            tour_guide_dict = {
                "id": guide.id,
                "bash_id": guide.bash_id,
                "user_id": guide.user_id,
                "tour_guide_name": guide.tour_guide_name,
                "card_type": guide.card_type,
                "card_number": guide.card_number,
                "travel_agency_card_num": guide.travel_agency_card_num,
                "travel_agency_phone": guide.travel_agency_phone,
                "status": guide.status,
                "updated_at": guide.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                "created_at": guide.created_at.strftime('%Y-%m-%d %H:%M:%S')
            }

            lvs = self.db.session.query(TravelAgency).filter(TravelAgency.bash_id == guide.bash_id,TravelAgency.grounp_id.in_(grounp_ids)).all()

            for lv in lvs:
                if lv.deleted == True:
                    raise FailException(f"该旅行社：{lv.travel_agency_name}已经被删除,请刷新后重试")
                agency_stop_key = f"reservation_stop:agency:{lv.id}"
                if self.redis_client.exists(agency_stop_key):
                    self.redis_client.delete(agency_stop_key)
                travel_agency_dict = {
                    "id": lv.id,
                    "bash_id": lv.bash_id,
                    "grounp_id": lv.id,
                    "travel_agency_name": lv.travel_agency_name,
                    "get_number": lv.get_number,
                    "order_no": lv.order_no,
                    "start_time": lv.start_time,
                    "end_time": lv.end_time,
                    "updated_at": lv.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                    "created_at": lv.created_at.strftime('%Y-%m-%d %H:%M:%S')
                }

                # 🔥 关键修改：为每个成员创建独立任务
                members = self.db.session.query(Member).filter(
                    Member.travel_agency_id == lv.id,
                    Member.grounp_id.in_(grounp_ids)
                ).all()

                for member in members:

                    with self.db.auto_commit():
                        if member.status in [TicketsStstaus.PADDING.value,TicketsStstaus.CANCELED.value,TicketsStstaus.STOP.value]:
                            member.status = TicketsStstaus.ERROR.value
                    member_dict = {
                        "id": member.id,
                        "bash_id": member.bash_id,
                        "travel_agency_id": member.travel_agency_id,
                        "status": member.status,
                        "playDate": member.playDate,
                        "created_at": member.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                        "updated_at": member.updated_at.strftime('%Y-%m-%d %H:%M:%S')
                    }

                    tasks.append(rservation.s(
                        bash_id=guide.bash_id,
                        agency_id=lv.id,
                        type=type,
                        secret_id=secret_id,
                        secret_key=secret_key,
                        grounp_id=member.grounp_id,
                        lv=json.dumps(travel_agency_dict),
                        tickets_bean=json.dumps(tour_guide_dict),
                        member=json.dumps(member_dict)
                    ))

        if not tasks:
            raise NotFoundException("没有找到需要处理的成员")

        job = group(tasks)
        result = job.apply_async()
    #删除导游及旅行社相关
    def del_tickets(self,bash_ids:list):
        for bash_id in bash_ids:
            batch_completed_key = f"batch_completed:{bash_id}"
            if self.redis_client.exists(batch_completed_key):
                self.redis_client.delete(batch_completed_key)
                print(f"🧹 删除批次时清除完成标志: {batch_completed_key}")
        with self.db.auto_commit():
            self.db.session.query(TourGuide).filter(TourGuide.bash_id.in_(bash_ids)).delete()
            self.db.session.query(TravelAgency).filter(TravelAgency.bash_id.in_(bash_ids)).delete()
            self.db.session.query(Member).filter(Member.bash_id.in_(bash_ids)).delete()
            self.db.session.query(MemberItem).filter(MemberItem.bash_id.in_(bash_ids)).delete()
    #删除旅行社
    def del_agency(self,agency_ids:list):
        with self.db.auto_commit():
            self.db.session.query(TravelAgency).filter(TravelAgency.id.in_(agency_ids)).update({
                "deleted":True
            })

    #删除成员
    def del_users(self,user_ids:list):
        with self.db.auto_commit():
            self.db.session.query(MemberItem).filter(MemberItem.id.in_(user_ids)).delete()
    #查看预约的记录
    def query_reservation_tickets(self, req: TicketsWithListPageSchema):
        from datetime import datetime
        with self.db.auto_commit():
           current_time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
           self.db.session.query(Member).filter(Member.end_time < current_time_str).update({
               "status": TicketsStstaus.TIME_OUT.value
           })

        paginator = Paginator(self.db, req)
        travel_agency_filters = []
        tour_guide_filters = []
        member_status=[
            TicketsStstaus.RESERVATION_SUCCESS.value,
            TicketsStstaus.ERROR.value,
            TicketsStstaus.STOP.value,
            TicketsStstaus.LAST_ERROR.value,
           TicketsStstaus.CANCELED.value,
            TicketsStstaus.TIME_OUT.value
        ]
        if  req.bash_id.data  and str(req.bash_id.data)!="":
            travel_agency_filters.append(TravelAgency.bash_id == req.bash_id.data)
            tour_guide_filters.append(TourGuide.bash_id == req.bash_id.data)

        if req.guide_name.data:
            tour_guide_filters.append(TourGuide.tour_guide_name.ilike(f"%{req.guide_name.data}%"))
        if req.travel_agencies_name.data:
            travel_agency_filters.append(TravelAgency.travel_agency_name.ilike(f"%{req.travel_agencies_name.data}%"))
        if req.status.data:
            member_status=[req.status.data]
        if req.created_date.data:
            travel_agency_filters.append(cast(TravelAgency.created_at, Date) == req.created_date.data)

        # 然后根据ID查询完整的TourGuide记录，按子查询中的created_at排序
        tour_guides_query =(self.db.session.query(TourGuide)
                    .filter(*tour_guide_filters)
                    .join(Member, TourGuide.bash_id == Member.bash_id)
                    .filter(Member.status.in_(member_status))
                    .group_by(TourGuide.id)  # 使用 GROUP BY 替代 DISTINCT
                    .order_by(desc(func.max(Member.created_at))))
        tour_guides_data = paginator.paginate(tour_guides_query)
        if not tour_guides_data:
            return [], paginator

        result_list = []

        # 按导游分组处理
        for tour_guide in tour_guides_data:
            # 组装导游基本信息
            tour_guide_dict = serialize_model(tour_guide, [
                'id', 'bash_id', 'created_at', 'end_time', 'get_number',
                'playDate', 'start_time', 'status', 'updated_at', 'tour_guide_name',
                'card_number', 'travel_agency_card_num', 'travel_agency_phone'
            ])
            # 查询该导游关联的所有旅行社
            travel_agencies_query = (
                self.db.session.query(TravelAgency)
                .filter(TravelAgency.bash_id == tour_guide.bash_id)
                .filter(*travel_agency_filters)
                .join(Member, TravelAgency.id == Member.travel_agency_id)
                .filter(Member.status.in_(
                  member_status
                )).order_by(desc("created_at")).all()
            )
            print(travel_agencies_query)

            # 查询该批次下的所有游客信息
            member_items = self.db.session.query(MemberItem).filter(
                MemberItem.bash_id == tour_guide.bash_id
            ).all()

            # 创建多个索引以便匹配
            member_items_by_card = {item.card_number: item for item in member_items if item.card_number}
            member_items_by_id = {item.id: item for item in member_items}

            # 按旅行社分组处理数据
            travel_agencies_list = []
            for travel_agency in travel_agencies_query:
                # 组装旅行社信息
                travel_agency_dict = serialize_model(travel_agency, [
                    'id', 'bash_id', 'card_number', 'card_type', 'created_at', 'deleted',
                    'end_time', 'get_number', 'order_no', 'start_time', 'grounp_id','status','playDate',
                    'travel_agency_card_num', 'travel_agency_name', 'travel_agency_phone', 'updated_at'
                ])
                print("status", travel_agency.get_member_data.status)
                travel_agency_dict["status"] = travel_agency.get_member_data.status
                # 查询该旅行社下的成员
                members = self.db.session.query(Member).filter(
                    Member.travel_agency_id == travel_agency.id,
                    Member.status.in_(member_status)
                ).all()
                # 🔧 修复：只包含成功关联到MemberItem的用户数据
                users_data = []

                for member in members:
                    # 🔧 修复：改进 MemberItem 关联逻辑
                    matched_member_item = None

                    # 方式1：通过 member_item_id 直接关联（最准确）
                    if hasattr(member, 'member_item_id') and member.member_item_id:
                        matched_member_item = member_items_by_id.get(member.member_item_id)

                    # 方式2：通过 card_number 匹配
                    if not matched_member_item and hasattr(member, 'card_number') and member.card_number:
                        matched_member_item = member_items_by_card.get(member.card_number)
                    # 🔧 修复：如果没有匹配到MemberItem，跳过这个Member
                    if not matched_member_item:
                        continue  # 跳过这个不完整的记录

                    # 成功匹配，组装完整用户数据
                    user_data = serialize_model(member, [
                        'id', 'bash_id', 'created_at', 'end_time', 'get_number',
                        'playDate', 'start_time', 'status', 'updated_at'
                    ])

                    # 添加MemberItem的详细信息
                    item_data = serialize_model(matched_member_item, [
                        'id', 'bash_id', 'card_number', 'card_type',
                        'origin', 'touristMobile', 'touristName'
                    ])
                    user_data.update(item_data)

                    users_data.append(user_data)
                    print(users_data)

                # 🔧 修复：直接使用MemberItem数据（确保数据完整性）
                # 对于没有对应Member记录的MemberItem，也包含在结果中
                used_member_item_ids = {user['id'] for user in users_data}
                for member_item in member_items:
                    if member_item.id not in used_member_item_ids:
                        # 检查这个MemberItem是否应该属于当前旅行社
                        if self._should_include_member_item(member_item, travel_agency):
                            user_data = {
                                'id': member_item.id,
                                'bash_id': member_item.bash_id,
                                'card_number': member_item.card_number,
                                'card_type': member_item.card_type,
                                'touristName': member_item.touristName,
                                'touristMobile': member_item.touristMobile,
                                'origin': member_item.origin,
                                'created_at': member_item.created_at.isoformat() if hasattr(member_item.created_at,
                                                                                            'isoformat') else str(
                                    member_item.created_at),
                                'updated_at': member_item.updated_at.isoformat() if hasattr(member_item.updated_at,
                                                                                            'isoformat') else str(
                                    member_item.updated_at),
                                'get_number': tour_guide_dict.get('get_number', 0)
                            }
                            users_data.append(user_data)

                # 只有存在用户数据时才包含这个旅行社
                if users_data:
                    travel_agency_with_users = {
                        **travel_agency_dict,
                        "users": users_data
                    }
                    travel_agencies_list.append(travel_agency_with_users)

            # 只有存在旅行社数据时才包含这个导游

            if travel_agencies_list:
                result_item = {
                    "tour_guide_info": tour_guide_dict,
                    "travel_agencies": travel_agencies_list
                }
                result_list.append(result_item)

        return result_list, paginator

    def _should_include_member_item(self, member_item, travel_agency):
        """
        判断MemberItem是否应该包含在当前旅行社中
        """
        # 简单的实现：如果MemberItem的grounp_id与旅行社的grounp_id相同就包含
        return member_item.grounp_id == travel_agency.grounp_id

    #预约
    def rservation_user(self,guide_marks:str,bash_id:str,guide_mobile:str,member_id:str,lvs_id:str,guide_id:str,proxy:dict):
        agency = self.db.session.query(TravelAgency).filter(TravelAgency.id == lvs_id).one_or_none()
        guide = self.db.session.query(TourGuide).filter(TourGuide.id == guide_id).one_or_none()
        cache = ACCESS_TOKEN.format(user_id=guide.user_id)
        token = self.redis_client.get(cache)
        req_session = requests.session()
        headers = get_headers(USER_SUB_URL, token)
        merge_headers = {
            **headers,
            "Authorization": f"Bearer {token}"
        }
        member = self.db.session.query(Member).filter(Member.id == member_id).one_or_none()
        member_items = self.db.session.query(MemberItem).filter(MemberItem.bash_id==bash_id,MemberItem.grounp_id ==member.grounp_id).all()

        data_rservation = self.query_sub_rservation(token, member.playDate,proxy)
        print( data_rservation.get("startTime"),data_rservation.get("endTime"))
        print("==============================time========================================")
        objs = {
            "guideMarks": guide_marks,
            "checkTime": data_rservation.get("index"),
            "playDate": member.playDate,
            "productId": "11324",
            "startTime": data_rservation.get("startTime"),
            "endTime": data_rservation.get("endTime"),
            "gateNumber": data_rservation.get("gateNumber"),
            "channelId": "01",
            "addTourists": [
                {
                    "touristName": item.touristName,
                    "cardType": item.card_type,
                    "cardNumber":item.card_number,
                    "touristMobile":item.touristMobile,
                    "nationality":"",
                    "origin":item.origin,
                    "sex":"",
                    "age":""
                }
                for item in member_items
            ],
            "delIds": [],
            "submitType": 1
        }
        print(objs)
        with self.db.auto_commit():
           try:
                req = req_session.request(
                    method="POST",
                    url=USER_SUB_URL,
                    json=objs,
                    proxies=proxy,
                    verify=False,
                    headers=merge_headers
                )
                data = req.json()

                print("================================status===============================")
                print(data)
                print(data.get("code"))
                print("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")
                print("================================status===============================")


                if data.get("code") in  ["1210024",1210024]:
                    desc = self.resvation_desc(member.playDate, data.get("data").get("id"), guide_mobile, token,3,proxy)
                    member.status = TicketsStstaus.RESERVATION_SUCCESS.value
                    member.start_time = data_rservation.get("startTime")
                    member.end_time = data_rservation.get("endTime")
                    member.get_number = data_rservation.get("gateNumber") if data_rservation.get("gateNumber") == 6 else 5
                    # 🔥 添加详细日志
                    print(f"🔄 更新前 member.status = {member.status}")
                    member.status = TicketsStstaus.RESERVATION_SUCCESS.value
                    print(f"✅ 更新后 member.status = {member.status}")
                    print(f"🔍 member.id = {member.id}")

                    agency.start_time = data_rservation.get("startTime")
                    agency.end_time = data_rservation.get("endTime")
                    agency.order_no = desc.get("id")
                    agency.get_number = data_rservation.get("gateNumber") if data_rservation.get("gateNumber") == 6 else 5

                    guide.status = TicketsStstaus.RESERVATION_SUCCESS.value  # 🔥 也更新导游状态
                    return True
                if data.get("code") in ["1200001", 1200001]:

                    # 查看预约详情
                    desc = self.resvation_desc(member.playDate, data.get("data").get("id"), guide_mobile, token,3,proxy)

                    if not agency:
                        raise FailException("团队不存在")

                    # 🔥 在同一个会话中更新成功状态
                    member.start_time = data_rservation.get("startTime")
                    member.end_time = data_rservation.get("endTime")
                    member.get_number = data_rservation.get("gateNumber") if data_rservation.get("gateNumber") == 6 else 5
                    # 🔥 添加详细日志
                    print(f"🔄 更新前 member.status = {member.status}")
                    member.status = TicketsStstaus.RESERVATION_SUCCESS.value
                    print(f"✅ 更新后 member.status = {member.status}")
                    print(f"🔍 member.id = {member.id}")

                    agency.start_time = data_rservation.get("startTime")
                    agency.end_time = data_rservation.get("endTime")
                    agency.order_no = desc.get("id")
                    agency.get_number = data_rservation.get("gateNumber") if data_rservation.get("gateNumber") == 6 else 5

                    guide.status = TicketsStstaus.RESERVATION_SUCCESS.value  # 🔥 也更新导游状态

                    print(f"✅ 成功更新状态: member_id={member_id}, status={member.status}")
                    return True
                else:
                    # 保持错误状态
                    guide.status = TicketsStstaus.ERROR.value
                    member.status = TicketsStstaus.ERROR.value
                    print(f"❌ 预约失败，保持错误状态: member_id={member_id}")
                    raise FailException(data.get("msg"))
           except Exception as e:
               raise  FailException(str(e))

     #查看预约详情
    def resvation_desc(self, pay_date: str, id: str, phone: str, token: str, max_retries:int,proxy:dict):
        """修复版本：添加重试机制的预约详情查询"""
        for attempt in range(max_retries):
            try:
                req_session = requests.session()
                url = f"{DETAILS_URL}/{pay_date}/{id}/{phone}?_={int(time.time() * 1000)}"
                headers = get_headers(url, token)
                merge_headers = {
                    **headers,
                    "Authorization": f"Bearer {token}"
                }

                # 添加随机延迟避免频率限制
                if attempt > 0:
                    delay = 0.5 * (attempt + 1)  # 递增延迟：0.5s, 1s, 1.5s
                    time.sleep(delay)

                req = req_session.get(
                    url=url,
                    verify=False,
                    proxies=proxy,
                    headers=merge_headers
                )
                data = req.json()

                if data.get("code") == 10006:
                    return data.get("data")
                else:
                    print(f"⚠️ resvation_desc 响应异常: {data.get('msg')}, 尝试 {attempt + 1}/{max_retries}")
                    if attempt == max_retries - 1:
                        raise FailException(f"获取预约详情失败: {data.get('msg')}")

            except Exception as e:
                print(f"⚠️ resvation_desc 请求异常: {str(e)}, 尝试 {attempt + 1}/{max_retries}")
                if attempt == max_retries - 1:
                    raise FailException(f"获取预约详情异常: {str(e)}")


    #查询可预约时间段
    def query_sub_rservation(self,token:str,play_date:str,proxy:dict):
        req_session = requests.session()
        args = {}
        #获取加密请求头
        headers = get_headers(PRODUCT_PC_URL, token)
        merge_headers = {
            **headers,
            "Authorization": f"Bearer {token}"
        }
        try:
            req = req_session.request(
                method="GET",
                url=f"{PRODUCT_PC_URL}",
                verify=False,
                proxies=proxy,
                headers=merge_headers
            )
            data = req.json()

            if data.get("code") == 10013:
                res = data.get("data")
                flag=False
                date_obj = res.get(play_date)
                if date_obj.get("status") == "kyy":
                    from datetime import datetime
                    # 按开始时间排序
                    sorted_timeline = sorted(
                        date_obj.get("timeLine", []),
                        key=lambda x: datetime.strptime(x["displayTimeStart"], "%H:%M")
                    )
                    #sorted_timeline[(len(sorted_timeline))-2:]:
                    print(
                        "============================================================query_sub_rservation_success==============================================")
                    print(sorted_timeline[:4])
                    print(
                        "============================================================query_sub_rservation_success==============================================")
                    for item in sorted_timeline[:4]:

                        if item.get("status") == "Y":
                            print("================================gateNumber=================================")
                            print(item.get("gateNumber"))
                            print("================================gateNumber=================================")
                            flag=True
                            args["gateNumber"] = item.get("gateNumber")
                            args["startTime"] = play_date + " " + item.get("displayTimeStart") + ":00"
                            args["endTime"] = play_date + " " + item.get("displayTimeEnd") + ":00"
                            args["index"] = item.get("typeNumber")
                            break
                    if not flag:
                        print("======================================预约失败，或房间已满==================================================")
                        raise FailException("预约失败，或房间已满")
                else:
                    print("=============================query_sub_rservation=================================")
                    print(data.get("msg"))
                    print("=============================query_sub_rservation=================================")

                    raise FailException("预约失败，或房间已满")
                return args
            else:
                print("====================query_sub_rservation===================")
                print(data.get("msg"))
                print("====================query_sub_rservation===================")
                raise FailException(data.get("msg"))
        except Exception as e:
            raise FailException(str(e))